#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
料盘详细视图对话框 - 增强版
支持网格布局、颜色编码、交互操作
"""

import tkinter as tk
from tkinter import ttk, messagebox
import math
from typing import List, Dict, Any, Callable

class PlateDetailDialog:
    """料盘详细视图对话框"""
    
    def __init__(self, parent, plate_name: str, positions: List[Dict[str, Any]], 
                 api_request_func: Callable = None):
        self.parent = parent
        self.plate_name = plate_name
        self.positions = positions
        self.api_request = api_request_func
        self.position_buttons = {}
        self.stat_cards = {}  # 存储统计卡片引用
        
        # 创建对话框 - 现代化样式，增加初始大小
        self.dialog = tk.Toplevel(parent)
        self.dialog.title(f"料盘详情 - {plate_name}")
        self.dialog.geometry("1200x800")  # 增加初始大小从900x650到1200x800
        self.dialog.configure(bg='#F8F9FA')  # 浅灰背景
        
        # 设置窗口属性 - 允许调整大小和标准窗口控制
        self.dialog.resizable(True, True)  # 允许水平和垂直调整大小
        self.dialog.minsize(800, 600)  # 设置最小尺寸
        
        # 居中显示
        self.center_dialog()
        
        # 创建界面
        self.create_widgets()
        
        # 绑定关闭事件
        self.dialog.protocol("WM_DELETE_WINDOW", self.on_close)
    
    def center_dialog(self):
        """居中显示对话框"""
        self.dialog.update_idletasks()
        x = self.parent.winfo_rootx() + (self.parent.winfo_width() // 2) - (1200 // 2)
        y = self.parent.winfo_rooty() + (self.parent.winfo_height() // 2) - (800 // 2)
        self.dialog.geometry(f"1200x800+{x}+{y}")
    
    def create_widgets(self):
        """创建界面组件"""
        main_frame = ttk.Frame(self.dialog, padding="10")
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        # 标题和统计信息
        self.create_header(main_frame)
        
        # 料盘网格视图
        self.create_grid_view(main_frame)
        
        # 详细信息面板
        self.create_detail_panel(main_frame)
        
        # 控制按钮
        self.create_control_buttons(main_frame)
    
    def create_header(self, parent):
        """创建标题和统计信息"""
        header_frame = tk.Frame(parent, bg='#F8F9FA')
        header_frame.pack(fill=tk.X, pady=(0, 15))
        
        # 标题
        title_label = tk.Label(header_frame, text=f"📋 料盘: {self.plate_name}", 
                              font=('Microsoft YaHei', 16, 'bold'),
                              bg='#F8F9FA', fg='#2C3E50')
        title_label.pack(side=tk.LEFT)
        
        # 统计信息卡片
        stats_frame = tk.Frame(header_frame, bg='#F8F9FA')
        stats_frame.pack(side=tk.RIGHT)
        
        stats = self.calculate_stats()
        
        # 创建统计卡片
        self.create_stat_card(stats_frame, "总计", stats['total'], "#3498DB", 0)
        self.create_stat_card(stats_frame, "可用", stats['available'], "#27AE60", 1)
        self.create_stat_card(stats_frame, "占用", stats['occupied'], "#E74C3C", 2)
        self.create_stat_card(stats_frame, "禁用", stats['disabled'], "#95A5A6", 3)
    
    def create_stat_card(self, parent, label, value, color, column):
        """创建统计卡片"""
        card_frame = tk.Frame(parent, bg=color, relief="flat", bd=0)
        card_frame.grid(row=0, column=column, padx=5, pady=0, ipadx=10, ipady=5)
        
        value_label = tk.Label(card_frame, text=str(value), 
                              font=('Microsoft YaHei', 12, 'bold'),
                              bg=color, fg='white')
        value_label.pack()
        
        label_label = tk.Label(card_frame, text=label, 
                              font=('Microsoft YaHei', 8),
                              bg=color, fg='white')
        label_label.pack()
        
        # 保存引用以便后续更新
        self.stat_cards[label] = value_label
    
    def calculate_stats(self) -> Dict[str, int]:
        """计算统计信息"""
        stats = {"total": len(self.positions), "available": 0, "occupied": 0, "disabled": 0}
        for pos in self.positions:
            stats[pos["status"]] += 1
        return stats
    
    def create_grid_view(self, parent):
        """创建网格视图"""
        grid_frame = tk.LabelFrame(parent, text="🔲 料盘布局", 
                                  font=('Microsoft YaHei', 12, 'bold'),
                                  bg='#F8F9FA', fg='#2C3E50',
                                  relief="flat", bd=1)
        grid_frame.pack(fill=tk.BOTH, expand=True, pady=(0, 15), padx=5)
        
        # 计算网格布局 - 优化布局计算
        total_positions = len(self.positions)
        # 根据料位数量智能计算列数，但不超过12列
        if total_positions <= 16:
            cols = min(4, total_positions)  # 小料盘最多4列
        elif total_positions <= 64:
            cols = min(8, math.ceil(math.sqrt(total_positions)))  # 中等料盘最多8列
        else:
            cols = min(12, math.ceil(math.sqrt(total_positions)))  # 大料盘最多12列
        
        rows = math.ceil(total_positions / cols)
        
        # 创建网格容器 - 限制最大高度
        container_frame = tk.Frame(grid_frame, bg='#F8F9FA')
        container_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        # 创建滚动区域来限制料位区域的高度
        canvas = tk.Canvas(container_frame, bg='#FFFFFF', highlightthickness=0)
        scrollbar = tk.Scrollbar(container_frame, orient="vertical", command=canvas.yview)
        self.grid_container = tk.Frame(canvas, bg='#FFFFFF', relief="flat", bd=1)
        
        # 配置滚动
        self.grid_container.bind('<Configure>', lambda e: canvas.configure(scrollregion=canvas.bbox("all")))
        canvas.create_window((0, 0), window=self.grid_container, anchor="nw")
        canvas.configure(yscrollcommand=scrollbar.set)
        
        # 动态计算高度，根据料位数量和窗口大小调整
        base_height = min(400, rows * 50)  # 基础高度
        canvas.configure(height=base_height)
        
        # 绑定窗口大小变化事件
        def on_resize(event):
            # 当窗口大小变化时，重新计算料位区域高度
            new_height = min(event.height - 300, rows * 50)  # 预留空间给其他组件
            canvas.configure(height=max(200, new_height))  # 最小200像素
        
        self.dialog.bind('<Configure>', on_resize)
        
        canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        
        for i, pos in enumerate(self.positions):
            row = i // cols
            col = i % cols
            
            # 创建料位按钮
            btn = self.create_position_button(self.grid_container, pos)
            btn.grid(row=row, column=col, padx=2, pady=2, sticky="nsew")
            
            self.position_buttons[pos["position_index"]] = btn
        
        # 配置网格权重
        for i in range(rows):
            self.grid_container.grid_rowconfigure(i, weight=1)
        for i in range(cols):
            self.grid_container.grid_columnconfigure(i, weight=1)
    
    def create_position_button(self, parent, position: Dict[str, Any]) -> tk.Button:
        """创建料位按钮"""
        pos_index = position["position_index"]
        status = position["status"]
        sample_id = position["sample_id"]
        
        # 确定按钮颜色和文本 - 现代化配色
        colors = {
            "available": {"bg": "#27AE60", "fg": "white", "active_bg": "#2ECC71"},    # 现代绿色
            "occupied": {"bg": "#E74C3C", "fg": "white", "active_bg": "#C0392B"},     # 现代红色
            "disabled": {"bg": "#95A5A6", "fg": "white", "active_bg": "#7F8C8D"}      # 现代灰色
        }
        
        color = colors.get(status, {"bg": "white", "fg": "black"})
        
        # 按钮文本
        if status == "occupied" and sample_id:
            # 智能处理样品ID显示
            if len(sample_id) > 16:
                # 如果超过16个字符，显示前14个+省略号
                display_id = sample_id[:14] + ".."
            else:
                display_id = sample_id
            text = f"{pos_index}\n{display_id}"
        else:
            text = str(pos_index)
        
        # 创建按钮 - 现代化样式
        btn = tk.Button(
            parent,
            text=text,
            width=12,  # 增加宽度从10到12，更好地利用空间
            height=3,  # 调整高度为3，平衡显示效果和空间占用
            bg=color["bg"],
            fg=color["fg"],
            activebackground=color["active_bg"],
            activeforeground="white",
            font=('Microsoft YaHei', 9, 'bold'),  # 增加字体大小从8到9
            relief="flat",
            borderwidth=0,
            cursor="hand2",
            command=lambda p=position: self.on_position_click(p)
        )
        
        # 添加工具提示
        self.create_tooltip(btn, position)
        
        return btn
    
    def create_tooltip(self, widget, position: Dict[str, Any]):
        """创建优化的工具提示"""
        tooltip_window = None
        
        def show_tooltip(event):
            nonlocal tooltip_window
            if tooltip_window:
                return  # 如果已有提示窗口，不重复创建
            
            tooltip_window = tk.Toplevel()
            tooltip_window.wm_overrideredirect(True)
            tooltip_window.wm_geometry(f"+{event.x_root+10}+{event.y_root+10}")
            tooltip_window.configure(bg='#2C3E50')  # 深蓝色背景
            
            status_text = {"available": "可用", "occupied": "占用", "disabled": "禁用"}[position["status"]]
            sample_text = position["sample_id"] if position["sample_id"] else "空"
            time_text = position["updated_at"][:19] if position["updated_at"] else "未知"
            
            text = f"料位: {position['position_index']}\n状态: {status_text}\n样品: {sample_text}\n更新: {time_text}"
            
            label = tk.Label(tooltip_window, text=text, 
                           background="#2C3E50", foreground="white",
                           relief="solid", borderwidth=1, 
                           font=('Microsoft YaHei', 9),
                           padx=8, pady=6)
            label.pack()
        
        def hide_tooltip(event=None):
            nonlocal tooltip_window
            if tooltip_window:
                tooltip_window.destroy()
                tooltip_window = None
        
        # 绑定事件
        widget.bind("<Enter>", show_tooltip)
        widget.bind("<Leave>", hide_tooltip)
        widget.bind("<Button-1>", hide_tooltip)  # 点击时也隐藏
    
    def create_detail_panel(self, parent):
        """创建详细信息面板"""
        detail_frame = tk.LabelFrame(parent, text="ℹ️ 详细信息", 
                                    font=('Microsoft YaHei', 12, 'bold'),
                                    bg='#F8F9FA', fg='#2C3E50',
                                    relief="flat", bd=1)
        detail_frame.pack(fill=tk.X, pady=(0, 15), padx=5)
        
        # 内容框架
        content_frame = tk.Frame(detail_frame, bg='#F8F9FA')
        content_frame.pack(fill=tk.X, padx=10, pady=10)
        
        # 选中料位信息
        self.selected_info = tk.Label(content_frame, text="💡 点击料位查看详细信息", 
                                     font=('Microsoft YaHei', 10),
                                     bg='#F8F9FA', fg='#7F8C8D')
        self.selected_info.pack(side=tk.LEFT)
        
        # 操作按钮
        self.action_frame = tk.Frame(content_frame, bg='#F8F9FA')
        self.action_frame.pack(side=tk.RIGHT)
        
        # 现代化按钮样式
        btn_style = {
            'font': ('Microsoft YaHei', 9, 'bold'),
            'relief': 'flat',
            'bd': 0,
            'cursor': 'hand2',
            'padx': 15,
            'pady': 8
        }
        
        self.enable_btn = tk.Button(self.action_frame, text="✅ 启用", 
                                   bg="#27AE60", fg="white",
                                   activebackground="#2ECC71",
                                   command=self.enable_position, state="disabled",
                                   **btn_style)
        self.enable_btn.pack(side=tk.LEFT, padx=(0, 8))
        
        self.disable_btn = tk.Button(self.action_frame, text="🚫 禁用", 
                                    bg="#E67E22", fg="white",
                                    activebackground="#D35400",
                                    command=self.disable_position, state="disabled",
                                    **btn_style)
        self.disable_btn.pack(side=tk.LEFT, padx=(0, 8))
        
        self.remove_btn = tk.Button(self.action_frame, text="🗑️ 移除样品", 
                                   bg="#E74C3C", fg="white",
                                   activebackground="#C0392B",
                                   command=self.remove_sample, state="disabled",
                                   **btn_style)
        self.remove_btn.pack(side=tk.LEFT)
        
        self.selected_position = None
    
    def create_control_buttons(self, parent):
        """创建控制按钮"""
        button_frame = tk.Frame(parent, bg='#F8F9FA')
        button_frame.pack(fill=tk.X, pady=(10, 0))
        
        # 现代化按钮样式
        btn_style = {
            'font': ('Microsoft YaHei', 10, 'bold'),
            'relief': 'flat',
            'bd': 0,
            'cursor': 'hand2',
            'padx': 20,
            'pady': 10
        }
        
        refresh_btn = tk.Button(button_frame, text="🔄 刷新", 
                               bg="#3498DB", fg="white",
                               activebackground="#2980B9",
                               command=self.refresh_data, **btn_style)
        refresh_btn.pack(side=tk.LEFT, padx=(0, 10))
        
        export_btn = tk.Button(button_frame, text="📊 导出", 
                              bg="#9B59B6", fg="white",
                              activebackground="#8E44AD",
                              command=self.export_data, **btn_style)
        export_btn.pack(side=tk.LEFT, padx=(0, 10))
        
        close_btn = tk.Button(button_frame, text="❌ 关闭", 
                             bg="#95A5A6", fg="white",
                             activebackground="#7F8C8D",
                             command=self.on_close, **btn_style)
        close_btn.pack(side=tk.RIGHT)
    
    def on_position_click(self, position: Dict[str, Any]):
        """料位点击事件"""
        self.selected_position = position
        pos_index = position["position_index"]
        status = position["status"]
        sample_id = position["sample_id"]
        
        # 更新详细信息显示 - 现代化样式
        status_text = {"available": "✅ 可用", "occupied": "🔴 占用", "disabled": "🚫 禁用"}[status]
        sample_text = sample_id if sample_id else "空"
        time_text = position["updated_at"][:19] if position["updated_at"] else "未知"
        
        info_text = f"📍 料位 {pos_index} | {status_text} | 📦 样品: {sample_text} | 🕒 更新: {time_text}"
        self.selected_info.config(text=info_text, fg='#2C3E50')
        
        # 更新按钮状态
        self.enable_btn.config(state="normal" if status == "disabled" else "disabled")
        self.disable_btn.config(state="normal" if status == "available" else "disabled")
        self.remove_btn.config(state="normal" if status == "occupied" else "disabled")
        
        # 高亮选中的按钮
        self.highlight_selected_position(pos_index)
    
    def highlight_selected_position(self, pos_index: int):
        """高亮选中的料位"""
        # 重置所有按钮边框
        for btn in self.position_buttons.values():
            btn.config(relief="flat", borderwidth=0)
        
        # 高亮选中的按钮 - 现代化样式
        if pos_index in self.position_buttons:
            self.position_buttons[pos_index].config(relief="solid", borderwidth=3, 
                                                   highlightbackground="#3498DB",
                                                   highlightcolor="#3498DB",
                                                   highlightthickness=2)
    
    def enable_position(self):
        """启用料位"""
        if not self.selected_position or not self.api_request:
            return
        
        try:
            pos_index = self.selected_position["position_index"]
            result = self.api_request("POST", f"/api/positions/enable/{self.plate_name}/{pos_index}")
            messagebox.showinfo("成功", result.get("message", "料位启用成功"))
            self.refresh_data()
        except Exception as e:
            messagebox.showerror("错误", f"启用料位失败: {str(e)}")
    
    def disable_position(self):
        """禁用料位"""
        if not self.selected_position or not self.api_request:
            return
        
        if not messagebox.askyesno("确认", "确定要禁用这个料位吗？"):
            return
        
        try:
            pos_index = self.selected_position["position_index"]
            result = self.api_request("POST", f"/api/positions/disable/{self.plate_name}/{pos_index}")
            messagebox.showinfo("成功", result.get("message", "料位禁用成功"))
            self.refresh_data()
        except Exception as e:
            messagebox.showerror("错误", f"禁用料位失败: {str(e)}")
    
    def remove_sample(self):
        """移除样品"""
        if not self.selected_position or not self.api_request:
            return
        
        sample_id = self.selected_position["sample_id"]
        if not sample_id:
            return
        
        if not messagebox.askyesno("确认", f"确定要移除样品 '{sample_id}' 吗？"):
            return
        
        try:
            result = self.api_request("DELETE", f"/api/samples/{self.plate_name}/{sample_id}")
            messagebox.showinfo("成功", result.get("message", "样品移除成功"))
            self.refresh_data()
        except Exception as e:
            messagebox.showerror("错误", f"移除样品失败: {str(e)}")
    
    def refresh_data(self):
        """刷新数据"""
        if not self.api_request:
            return
        
        try:
            result = self.api_request("GET", f"/api/plates/{self.plate_name}/positions")
            self.positions = result["positions"]
            self.update_display()
        except Exception as e:
            messagebox.showerror("错误", f"刷新数据失败: {str(e)}")
    
    def update_display(self):
        """更新显示"""
        # 更新按钮显示
        for pos in self.positions:
            pos_index = pos["position_index"]
            if pos_index in self.position_buttons:
                btn = self.position_buttons[pos_index]
                
                # 更新颜色 - 现代化配色
                colors = {
                    "available": {"bg": "#27AE60", "fg": "white", "active_bg": "#2ECC71"},
                    "occupied": {"bg": "#E74C3C", "fg": "white", "active_bg": "#C0392B"},
                    "disabled": {"bg": "#95A5A6", "fg": "white", "active_bg": "#7F8C8D"}
                }
                color = colors.get(pos["status"], {"bg": "white", "fg": "black", "active_bg": "lightgray"})
                btn.config(bg=color["bg"], fg=color["fg"], activebackground=color["active_bg"])
                
                # 更新文本
                if pos["status"] == "occupied" and pos["sample_id"]:
                    text = f"{pos_index}\n{pos['sample_id'][:8]}"
                else:
                    text = str(pos_index)
                btn.config(text=text)
        
        # 更新统计信息卡片
        stats = self.calculate_stats()
        if "总计" in self.stat_cards:
            self.stat_cards["总计"].config(text=str(stats['total']))
        if "可用" in self.stat_cards:
            self.stat_cards["可用"].config(text=str(stats['available']))
        if "占用" in self.stat_cards:
            self.stat_cards["占用"].config(text=str(stats['occupied']))
        if "禁用" in self.stat_cards:
            self.stat_cards["禁用"].config(text=str(stats['disabled']))
        
        # 清除选中状态
        self.selected_position = None
        self.selected_info.config(text="💡 点击料位查看详细信息", fg='#7F8C8D')
        self.enable_btn.config(state="disabled")
        self.disable_btn.config(state="disabled")
        self.remove_btn.config(state="disabled")
        
        # 重置所有按钮边框
        for btn in self.position_buttons.values():
            btn.config(relief="flat", borderwidth=0)
    
    def export_data(self):
        """导出数据"""
        try:
            from tkinter import filedialog
            import csv
            
            filename = filedialog.asksaveasfilename(
                title="导出料盘数据",
                defaultextension=".csv",
                filetypes=[("CSV文件", "*.csv"), ("所有文件", "*.*")]
            )
            
            if filename:
                with open(filename, 'w', newline='', encoding='utf-8') as csvfile:
                    writer = csv.writer(csvfile)
                    writer.writerow(["料位", "样品ID", "状态", "更新时间"])
                    
                    for pos in self.positions:
                        status_text = {"available": "可用", "occupied": "占用", "disabled": "禁用"}[pos["status"]]
                        sample_text = pos["sample_id"] if pos["sample_id"] else "空"
                        time_text = pos["updated_at"][:19] if pos["updated_at"] else ""
                        
                        writer.writerow([pos["position_index"], sample_text, status_text, time_text])
                
                messagebox.showinfo("成功", f"数据已导出到: {filename}")
        except Exception as e:
            messagebox.showerror("错误", f"导出失败: {str(e)}")
    
    def on_close(self):
        """关闭对话框"""
        self.dialog.destroy() 